package user

import (
	"gorm.io/gorm"
)

// Repository 用户数据访问层接口
type Repository interface {
	Create(user *User) error
	GetByID(id uint) (*User, error)
	GetByUsername(username string) (*User, error)
	GetByEmail(email string) (*User, error)
	Update(user *User) error
	Delete(id uint) error
	List(req *QueryRequest) ([]*UserWithRoles, int64, error)
	UpdateRoles(userID uint, roleIDs []uint) error
	GetUserWithRoles(id uint) (*UserWithRoles, error)
}

// repository 用户数据访问层实现
type repository struct {
	db *gorm.DB
}

// NewRepository 创建用户数据访问层
func NewRepository(db *gorm.DB) Repository {
	return &repository{
		db: db,
	}
}

// Create 创建用户
func (r *repository) Create(user *User) error {
	return r.db.Create(user).Error
}

// GetByID 根据ID获取用户
func (r *repository) GetByID(id uint) (*User, error) {
	var user User
	err := r.db.First(&user, id).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// GetByUsername 根据用户名获取用户
func (r *repository) GetByUsername(username string) (*User, error) {
	var user User
	err := r.db.Where("username = ?", username).First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// GetByEmail 根据邮箱获取用户
func (r *repository) GetByEmail(email string) (*User, error) {
	var user User
	err := r.db.Where("email = ?", email).First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// Update 更新用户
func (r *repository) Update(user *User) error {
	return r.db.Save(user).Error
}

// Delete 删除用户
func (r *repository) Delete(id uint) error {
	return r.db.Delete(&User{}, id).Error
}

// List 获取用户列表
func (r *repository) List(req *QueryRequest) ([]*UserWithRoles, int64, error) {
	var users []*User
	var total int64

	query := r.db.Model(&User{})

	// 关键词搜索
	if req.Keyword != "" {
		query = query.Where("username LIKE ? OR email LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 字段筛选
	if req.Username != "" {
		query = query.Where("username = ?", req.Username)
	}

	if req.Email != "" {
		query = query.Where("email = ?", req.Email)
	}

	if req.Status != nil {
		query = query.Where("status = ?", *req.Status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Order("id DESC").Find(&users).Error; err != nil {
		return nil, 0, err
	}

	// 手动组装带角色的用户列表
	var result []*UserWithRoles
	for _, user := range users {
		// 使用模型查询每个用户的角色
		var userRoles []UserRole
		err := r.db.Preload("Role").Where("user_id = ?", user.ID).Find(&userRoles).Error
		if err != nil {
			return nil, 0, err
		}

		// 提取角色信息
		var roles []Role
		for _, ur := range userRoles {
			roles = append(roles, ur.Role)
		}

		// 组装结果
		userWithRoles := &UserWithRoles{
			ID:        user.ID,
			Username:  user.Username,
			Nickname:  user.Nickname,
			Email:     user.Email,
			Phone:     user.Phone,
			Avatar:    user.Avatar,
			Status:    user.Status,
			LastLogin: user.LastLogin,
			CreatedAt: user.CreatedAt,
			UpdatedAt: user.UpdatedAt,
			Roles:     roles,
		}
		result = append(result, userWithRoles)
	}

	return result, total, nil
}

// UpdateRoles 更新用户角色
func (r *repository) UpdateRoles(userID uint, roleIDs []uint) error {
	// 使用模型删除现有角色关联
	if err := r.db.Where("user_id = ?", userID).Delete(&UserRole{}).Error; err != nil {
		return err
	}

	// 如果有新角色，则使用模型添加关联
	if len(roleIDs) > 0 {
		var userRoles []UserRole
		for _, roleID := range roleIDs {
			userRoles = append(userRoles, UserRole{
				UserID: userID,
				RoleID: roleID,
			})
		}
		if err := r.db.Create(&userRoles).Error; err != nil {
			return err
		}
	}

	return nil
}

// GetUserWithRoles 获取带角色信息的用户
func (r *repository) GetUserWithRoles(id uint) (*UserWithRoles, error) {
	// 先获取用户基本信息
	var user User
	err := r.db.First(&user, id).Error
	if err != nil {
		return nil, err
	}

	// 使用模型查询用户角色
	var userRoles []UserRole
	err = r.db.Preload("Role").Where("user_id = ?", id).Find(&userRoles).Error
	if err != nil {
		return nil, err
	}

	// 提取角色信息
	var roles []Role
	for _, ur := range userRoles {
		roles = append(roles, ur.Role)
	}

	// 构建返回结果
	userWithRoles := &UserWithRoles{
		ID:        user.ID,
		Username:  user.Username,
		Nickname:  user.Nickname,
		Email:     user.Email,
		Phone:     user.Phone,
		Avatar:    user.Avatar,
		Status:    user.Status,
		LastLogin: user.LastLogin,
		CreatedAt: user.CreatedAt,
		UpdatedAt: user.UpdatedAt,
		Roles:     roles,
	}

	return userWithRoles, nil
}
